package org.paradise.dms.services.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;
import org.paradise.dms.dao.impl.DormitoryChargeDAOImpl;
import org.paradise.dms.dao.impl.DormitoryDAOImpl;
import org.paradise.dms.dao.impl.StudentBedLinkDAOImpl;
import org.paradise.dms.dao.impl.StudentDAOImpl;
import org.paradise.dms.pojo.AllocationInfo;
import org.paradise.dms.pojo.Dormitory;
import org.paradise.dms.pojo.Student;
import org.paradise.dms.pojo.StudentBedLink;
import org.paradise.dms.services.StudentLodgeMgrService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.dheaven.framework.dao.DaoException;

@Service
public class StudentLodgeMgrServiceImpl implements StudentLodgeMgrService {
	private static Logger log = Logger.getLogger(StudentLodgeMgrServiceImpl.class);
	@Autowired
	private StudentDAOImpl studentDAOImpl;
	@Autowired
	private DormitoryDAOImpl dormitoryDAOImpl;
	@Autowired
	private StudentBedLinkDAOImpl studentbedlinkDAOImpl;
	@Autowired
	private DormitoryChargeDAOImpl dormitorychargeDAOImpl;

	/*
	 * 根据学号查询学生
	 */
	@SuppressWarnings("unchecked")
	public List searchStudentByStudentNo(String studentno) throws DaoException {
		// return (List<Student>)
		return studentDAOImpl.getStudentByStudentNo(studentno);
		// 4月26日 李双江修改调用了zh的方法. 取消了泛型
		// return studentDAOImpl.getStudentBasicInfo(studentno);
	}

	/*
	 * 根据公寓id, 宿舍号查询宿舍
	 */
	public List<Dormitory> getDormByApartIdAndDormName(String apartid, String dormName,int studentdormitorytpye) throws DaoException {
		return (List<Dormitory>) dormitoryDAOImpl.getDormByApartIdAndDormName(apartid, dormName,studentdormitorytpye);
	}

	/**
	 * 根据学生id, 宿舍id进行分配
	 */
	public String allocateSingleStudent(int studentid, int dormitoryid) throws DaoException {
		String statusMsg = studentbedlinkDAOImpl.insertStudentBedLink(studentid, dormitoryid);
		// System.out.println(statusMsg + ", 吐吐吐");
		// log.info(statusMsg + ", 吐吐吐");
		if ("".equals(statusMsg)) {
			Student student = studentDAOImpl.getStudent(studentid);
			Dormitory dormitory = dormitoryDAOImpl.getDormByDormId(dormitoryid).get(0);
			statusMsg = "";
			return statusMsg;
		}
		return statusMsg;
	}

	/**
	 * 根据两学生id 对其宿舍床位进行交换
	 */
	public String swapStudents(int studentidA, int studentidB) {
		String statusMsg = "";
		StudentBedLink studentA;
		try {
			List<StudentBedLink> lstA = studentbedlinkDAOImpl.getStudentBedLinkByStudentId(studentidA);
			if (lstA.size() == 0) {
				statusMsg = "学生" + studentidA + "尚未分配宿舍";
				log.warn("DMS_warn:" + statusMsg);
				return statusMsg;
			}
			studentA = lstA.get(0);
		} catch (DaoException e) {
			statusMsg = "学生" + studentidA + "住宿信息获取失败！";
			log.error("DMS_error:" + statusMsg);
			log.error("DMS_error: 失败原因" + e);
			return statusMsg;
		}
		StudentBedLink studentB;
		try {
			List<StudentBedLink> lstB = studentbedlinkDAOImpl.getStudentBedLinkByStudentId(studentidB);
			if (lstB.size() == 0) {
				statusMsg = "学生" + studentidB + "尚未分配宿舍";
				log.warn("DMS_warn:" + statusMsg);
				return statusMsg;
			}
			studentB = lstB.get(0);
		} catch (DaoException e) {
			statusMsg = "学生" + studentidB + "住宿信息获取失败！";
			log.error("DMS_error:" + statusMsg);
			log.error("DMS_error: 失败原因" + e);
			return statusMsg;
		}
		
		//如果住宿人员的类型不同,不允许调换宿舍
		Student s1 = studentDAOImpl.getStudent(studentidA);
		Student s2 = studentDAOImpl.getStudent(studentidB);
		if(s1.getStudentdormitorytype() != s2.getStudentdormitorytype()){
			statusMsg = "住宿人员类型不同,不可调换！";
			return statusMsg;
		}
		
		
		statusMsg += studentA.getStudentid() + "_" + studentbedlinkDAOImpl.insertAccomodationHistory(studentA.getDormitoryid(), studentA.getDormitorybedid(), studentA.getStudentid(), studentA.getStudentbedstartintime(), new Date()) + ", ";
		statusMsg += studentB.getStudentid() + "_" + studentbedlinkDAOImpl.insertAccomodationHistory(studentB.getDormitoryid(), studentB.getDormitorybedid(), studentB.getStudentid(), studentB.getStudentbedstartintime(), new Date()) + ", ";

		int tempBedId = studentA.getDormitorybedid();

		studentA.setDormitorybedid(studentB.getDormitorybedid());
		studentB.setDormitorybedid(tempBedId);

		int tempDormId = studentA.getDormitoryid();

		studentA.setDormitoryid(studentB.getDormitoryid());
		studentB.setDormitoryid(tempDormId);

		studentA.setStudentbedstartintime(new Date());
		studentB.setStudentbedstartintime(new Date());

		try {
			studentbedlinkDAOImpl.update(studentA);
			studentbedlinkDAOImpl.update(studentB);
		} catch (DaoException e) {
			statusMsg += "调换学生宿舍失败！";
			log.error("DMS_error:调换学生" + studentidA + ", " + studentidB + "宿舍失败");
			log.error("DMS_error:失败原因 " + e);
			return statusMsg;
		}
		statusMsg += "调换学生宿舍成功！";
		log.info("DMS_info:调换学生" + studentidA + ", " + studentidB + "宿舍成功");
		return statusMsg;
	}

	/**
	 * 根据学生id，宿舍id 将学生调换至新宿舍的空床上
	 */
	public String transferSingleStudentToEmptyBed(int studentid, int dormitoryid) throws DaoException {
		return studentbedlinkDAOImpl.updateStudentBedLink(studentid, dormitoryid);
	}

	/**
	 * 根据学生id，宿舍id，入住时间，住宿结束时间进行分配
	 */
	public String allocateSingleStudent(int studentid, int dormitoryid, Date studentbedstartintime, Date studentbedendouttime) throws DaoException {
		String statusMsg = studentbedlinkDAOImpl.insertStudentBedLink(studentid, dormitoryid, studentbedstartintime, studentbedendouttime);

		if ("".equals(statusMsg)) {
			Student student = studentDAOImpl.getStudent(studentid);
			Dormitory dormitory = dormitoryDAOImpl.getDormByDormId(dormitoryid).get(0);
			statusMsg = "";
			return statusMsg;
		}
		return statusMsg;
	}

	/**
	 * 根据学生id办理退宿
	 * 
	 * @throws DaoException
	 */
	public String studentCheckOut(int studentid) throws DaoException {
		return studentbedlinkDAOImpl.deleteStudentBedLink(studentid);

	}

	/**
	 * 根据学号查询住宿信息
	 */
	@SuppressWarnings("unchecked")
	public List queryStudentLodgeInfo(String studentno) throws DaoException {
		List myList = new ArrayList();
		List<Student> list = (List<Student>) studentDAOImpl.getStudentByStudentNo(studentno);
		if (list != null && list.size() > 0) {
			Student student = list.get(0);
			List<StudentBedLink> stubedList = studentbedlinkDAOImpl.getStudentBedLinkByStudentId(student.getStudentid());
			if (stubedList != null && stubedList.size() > 0) {
				List<Dormitory> dl = dormitoryDAOImpl.getDormByDormId(stubedList.get(0).getDormitoryid());
				if (dl != null && dl.size() > 0) {
					Dormitory dormitory = dl.get(0);
					myList.add(0, student);
					myList.add(1, dormitory);
					myList.add(2, "containsdorm");
				} else {
					myList.add(0, student);
					myList.add(1, "宿舍床位表的学生信息在宿舍表中不存在");
				}
			} else {
				myList.add(0, student);
				myList.add(1, "该学生尚未分配宿舍");
			}
			return myList;
		}
		return null;
	}

	/**
	 * 根据宿舍id查询其信息
	 * 
	 * @throws DaoException
	 */
	public List<Dormitory> getDormByDormId(int dormitoryid) throws DaoException {
		return dormitoryDAOImpl.getDormByDormId(dormitoryid);
	}

	public List<StudentBedLink> getStudentBedLinkByStudentId(int studentid) throws DaoException {
		return studentbedlinkDAOImpl.getStudentBedLinkByStudentId(studentid);
	}

	/**
	 * 根据sql语句进行批量退宿
	 */
	public String studentBatchCheckout(String sql) {
		return studentbedlinkDAOImpl.deleteBatchStudentBedLink(sql);
	}

	public List<AllocationInfo> getAllAllocationInfo() {
		return dormitoryDAOImpl.getAllAllocationInfo();
	}

	/**
	 * 根据学生list、宿舍list进行批量分配
	 */
	@SuppressWarnings("unchecked")
	public String allocateBatchStudent(String[][] stuList, String[][] dormitoryList, Date startintime, Date endouttime,String order) {
		String studentId = "";
		String studentName = "";
		String studentEnrollYear = "";
		String studentEducationYear = "";
		String dormitoryBedId = "";
		String dormitoryFee = "";

		StringBuffer statusMsg = new StringBuffer("");

		List dormitoryBedList = new ArrayList();
		int dormitoryIndex = 0;
		int dormitoryBedIndex = 0;

		// studentIndex首次循环，此时尚未有床位列表存在
		// do： 根据当前宿舍索引从该宿舍中取出床位列表
		if (dormitoryIndex >= dormitoryList.length) {
			statusMsg.append("Error: 宿舍床位数 < 学生数");
			log.error("DMS_error:宿舍数目不足");
			return statusMsg.toString();
		}
		
		
		//========================kevin add ==========================
		//如果是逆序分配，则从宿舍列表最大的索引值开始
		if("desc".equals(order)){
			dormitoryIndex = dormitoryList.length - 1;
		}
		//----------------------------add end ----------------------------
		

		// 取床位列表；将床位索引置零
		dormitoryBedList = dormitoryDAOImpl.getAvailBedByDormId(dormitoryList[dormitoryIndex][0]);
		dormitoryFee = dormitoryList[dormitoryIndex][2];
		dormitoryBedIndex = 0;
		System.out.println("宿舍索引值：" + dormitoryIndex + ", 宿舍号：" + dormitoryList[dormitoryIndex][1] + ", 宿舍可用床位数:" + dormitoryBedList.size() + ", 当前床位索引值:" + dormitoryBedIndex + "住宿费:" + dormitoryList[dormitoryIndex][2]);

		// 情况2：刚刚取到的床位列表为空
		// 情况3：已有的床位列表中床位已分配尽
		// do： 删除当前宿舍预分配标记；dormitoryIndex++，从下一个宿舍中取床位列表
		if ((dormitoryBedList.size() == 0) || (dormitoryBedIndex >= dormitoryBedList.size())) {
			do {
				// 删除该宿舍预分配标记
				while (!dormitoryDAOImpl.deleteDormitoryPreassignedId(dormitoryList[dormitoryIndex][0]))
					;
				statusMsg.append("已删除_" + (String) dormitoryList[dormitoryIndex][1] + "_预分配标记, ");
				log.info("DMS_info:宿舍" + dormitoryList[dormitoryIndex][1] + "已满，已删除其预分配标记");

				//========================kevin add ==========================
				//如果是逆序分配，则从宿舍列表最大的索引值开始
				if("desc".equals(order)){
					dormitoryIndex--;
				}
				//----------------------------add end ----------------------------
				else dormitoryIndex++;

			
				//========================kevin add ==========================
				//如果是逆序分配，则从宿舍列表最大的索引值开始
				if("desc".equals(order)){
					if (dormitoryIndex < 0) {
						statusMsg.append("Error: 宿舍床位数 < 学生数");
						log.error("DMS_error:宿舍数目不足");
						return statusMsg.toString();
					}
				}
				//----------------------------add end ----------------------------
				// 如果宿舍已用尽，停止分配并返回错误信息
				else if (dormitoryIndex >= dormitoryList.length) {
					statusMsg.append("Error: 宿舍床位数 < 学生数");
					log.error("DMS_error:宿舍数目不足");
					return statusMsg.toString();
				}

				// 取床位列表；将床位索引置零
				dormitoryBedList = dormitoryDAOImpl.getAvailBedByDormId(dormitoryList[dormitoryIndex][0]);
				dormitoryBedIndex = 0;
				dormitoryFee = dormitoryList[dormitoryIndex][2];

				System.out.println("宿舍索引值：" + dormitoryIndex + ", 宿舍号：" + dormitoryList[dormitoryIndex][1] + ", 宿舍可用床位数:" + dormitoryBedList.size() + ", 当前床位索引值:" + dormitoryBedIndex + "住宿费:" + dormitoryList[dormitoryIndex][2]);

			} while (dormitoryBedList.size() == 0); // 第二步 情况4：
			// 如果刚刚取到的床位列表为空，则再取一次
		}
		System.out.println("stuList.length:" + stuList.length);
		System.out.println("dormList:" + dormitoryList.length);

		// 遍历学生列表
		for (int studentIndex = 0; studentIndex < stuList.length; studentIndex++) {

			// 第一步 取出当前学生ID、NAME
			studentId = (String) stuList[studentIndex][0];
			studentName = (String) stuList[studentIndex][1];
			studentEnrollYear = (String) stuList[studentIndex][2];
			studentEducationYear = (String) stuList[studentIndex][3];

			System.out.println("stulist" + (String) stuList[studentIndex][2] + (String) stuList[studentIndex][3]);

			// 第二步 取得一个宿舍中的床位列表
			// 情况5： 当前床位列表中有可用床位
			// 第三步 从床位列表中取出一个床位的ID
			dormitoryBedId = dormitoryBedList.get(dormitoryBedIndex) + "";

			System.out.println("宿舍索引值：" + dormitoryIndex + ", 宿舍号：" + dormitoryList[dormitoryIndex][1] + ", 宿舍可用床位数:" + dormitoryBedList.size() + ", 当前床位索引值:" + dormitoryBedIndex);
			System.out.println("dormlist" + dormitoryList[dormitoryIndex][2]);

			// 第四步 根据学生id、宿舍id、床位id进行分配。 如果分配失败，则停止分配并返回错误信息
			String allocateMsg = studentbedlinkDAOImpl.insertStudentBedLink(studentId, dormitoryList[dormitoryIndex][0], dormitoryBedId, startintime, endouttime);

			// 第四步
			// 情况1： DAO层操作失败。
			// do： 记录错误信息，停止分配。
			if ("Error".equals(allocateMsg)) {
				statusMsg.append(studentName + "_DAO层操作失败");
				return statusMsg.toString();
			} else if ("delPreAssignedID".equals(allocateMsg)) {

				// 第四步
				// 情况2： 该学生已获分配
				// do： 记录“已分配”信息，DAO层删除其预分配标记
				// Caution： 由于该学生已获分配，所以此时获取到的dormitoryBedId并未使用，还可以留给下一名学生使用
				// 所以此时dormitoryBedIndex不++
				statusMsg.append(studentName + "_已获分配, ");
				log.info("DMS_info:学生" + studentName + "已获分配，已删除其预分配标记(student already allocated)");
			} else if ("inserted".equals(allocateMsg)) {

				// 第四步
				// 情况3： 分配成功
				statusMsg.append(studentName + "_" + dormitoryList[dormitoryIndex][1] + "_分配成功, ");
				System.out.print(studentName + "_" + dormitoryList[dormitoryIndex][1] + "_分配成功, ");

				// 第五步 删除学生预分配标记
				// 床位索引自增
				while (!studentDAOImpl.deleteStudentpreassignedID(studentId))
					;

				
				// statusMsg.append("已删除_" + studentName + "_预分配标记, ");
				System.out.println("已删除_" + studentName + "_预分配标记, ");
				log.info("DMS_info:学生" + studentName + "分配成功，已删除其预分配标记(student allocate succeeded)");
				dormitoryBedIndex++;

				// 判断床位列表是否用尽
				if ((dormitoryBedList.size() == 0) || (dormitoryBedIndex >= dormitoryBedList.size())) {

					do {
						// 删除该宿舍预分配标记
						while (!dormitoryDAOImpl.deleteDormitoryPreassignedId(dormitoryList[dormitoryIndex][0]))
							;
						// statusMsg.append("已删除_" + (String)
						// dormitoryList[dormitoryIndex][1] + "_预分配标记, ");

						log.info("DMS_info:宿舍" + dormitoryList[dormitoryIndex][1] + "已满，已删除其预分配标记");

						//========================kevin add ==========================
						//如果是逆序分配，则从宿舍列表最大的索引值开始
						if("desc".equals(order)){
							dormitoryIndex--;
						}
						//----------------------------add end ----------------------------
						else dormitoryIndex++;

						// 如果最后一名学生已分配完毕，则跳出取床位列表的do-while循环
						if (studentIndex + 1 >= stuList.length) {
							break;
						}

						//========================kevin add ==========================
						//如果是逆序分配，则从宿舍列表最大的索引值开始
						if("desc".equals(order)){
							if (dormitoryIndex < 0) {
								statusMsg.append("Error: 宿舍床位数 < 学生数");
								log.error("DMS_error:宿舍数目不足");
								return statusMsg.toString();
							}
						}
						//----------------------------add end ----------------------------
						// 如果宿舍已用尽，停止分配并返回错误信息
						else if (dormitoryIndex >= dormitoryList.length) {
							statusMsg.append("Error: 宿舍床位数 < 学生数");
							log.error("DMS_error:宿舍数目不足");
							return statusMsg.toString();
						}

						// 取床位列表；将床位索引置零
						dormitoryBedList = dormitoryDAOImpl.getAvailBedByDormId(dormitoryList[dormitoryIndex][0]);
						dormitoryBedIndex = 0;
						dormitoryFee = dormitoryList[dormitoryIndex][2];

						System.out.println("宿舍索引值：" + dormitoryIndex + ", 宿舍号：" + dormitoryList[dormitoryIndex][1] + ", 宿舍可用床位数:" + dormitoryBedList.size() + ", 当前床位索引值:" + dormitoryBedIndex + "住宿费:" + dormitoryList[dormitoryIndex][2]);

					} while (dormitoryBedList.size() == 0); // 如果刚刚取到的床位列表为空，则再取一次
				}
			}
		}
		return statusMsg.toString();
	}

	public StudentDAOImpl getStudentDAOImpl() {
		return studentDAOImpl;
	}

	public void setStudentDAOImpl(StudentDAOImpl studentDAOImpl) {
		this.studentDAOImpl = studentDAOImpl;
	}

	public DormitoryDAOImpl getDormitoryDAOImpl() {
		return dormitoryDAOImpl;
	}

	public void setDormitoryDAOImpl(DormitoryDAOImpl dormitoryDAOImpl) {
		this.dormitoryDAOImpl = dormitoryDAOImpl;
	}

	public StudentBedLinkDAOImpl getStudentbedlinkDAOImpl() {
		return studentbedlinkDAOImpl;
	}

	public void setStudentbedlinkDAOImpl(StudentBedLinkDAOImpl studentbedlinkDAOImpl) {
		this.studentbedlinkDAOImpl = studentbedlinkDAOImpl;
	}

	public DormitoryChargeDAOImpl getDormitorychargeDAOImpl() {
		return dormitorychargeDAOImpl;
	}

	public void setDormitorychargeDAOImpl(DormitoryChargeDAOImpl dormitorychargeDAOImpl) {
		this.dormitorychargeDAOImpl = dormitorychargeDAOImpl;
	}

	@SuppressWarnings("unchecked")
	public List getLodgeTimeByStudentNo(String studentno) {
		return studentbedlinkDAOImpl.getLodgeTimeByStudentNo(studentno);
	}

	public String updateStudentLodgeTime(String studentid, Date startintime, Date endouttime) {
		return studentbedlinkDAOImpl.updateStudentLodgeTime(studentid, startintime, endouttime);
	}

	public String studentBatchCheckout(String[] stuIdList) {
		StringBuffer stuIdString = new StringBuffer("");
		stuIdString.append("where studentid in {");

		// 如果有N个ID，那么先将N-1个加入字符串 每个后面加分隔符", "
		for (int i = 0; i < (stuIdList.length - 1); i++) {
			stuIdString.append(stuIdList[i]);
			stuIdString.append(", ");
		}

		// 将第N个ID加入字符串，后面加"}"
		stuIdString.append(stuIdList[stuIdList.length - 1]);
		stuIdString.append("}");
		return studentbedlinkDAOImpl.deleteBatchStudentBedLink(stuIdString.toString());
	}

	public int getAvailInDormAmountByDormId(String dormid) {
		return studentbedlinkDAOImpl.getAvailInDormAmountByDormId(dormid);
	}
	
	public List getPreassignDateByPreID(int id){
		return studentbedlinkDAOImpl.getPreassignDateByPreID(id);
	}
	
}
